package com.ruoyi.file.utils;

import com.ruoyi.file.domain.SysStorageConfig;
import com.ruoyi.file.enums.StorageTypeEnum;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3ClientBuilder;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.sts.StsClient;

import java.net.URI;

/**
 * S3客户端工厂工具类
 * 统一创建各种S3相关客户端的逻辑
 *
 * @author ruoyi
 */
public class S3ClientFactory {


    /**
     * 创建S3客户端（使用StorageService实例的配置）
     *
     * @param config 存储配置
     * @param storageService 存储服务实例
     * @return S3客户端
     */
    public static S3Client createS3Client(SysStorageConfig config, com.ruoyi.file.service.storage.StorageService storageService) {
        AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(
                config.getAccessKey(),
                config.getSecretKey()
        );

        String regionString = resolveRegion(config);
        S3ClientBuilder builder = S3Client.builder()
                .credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
                .endpointOverride(URI.create(config.getEndpoint()))
                .region(Region.of(regionString));

        // 使用StorageService实例的配置
        if (storageService instanceof com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl) {
            com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl baseService = 
                (com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl) storageService;
            builder.forcePathStyle(baseService.shouldUsePathStyle());
        } else {
            // 回退到默认配置（虚拟主机风格）
            builder.forcePathStyle(false);
        }

        return builder.build();
    }


    /**
     * 创建S3预签名器（使用StorageService实例的配置）
     *
     * @param config 存储配置
     * @param storageService 存储服务实例
     * @return S3预签名器
     */
    public static S3Presigner createS3Presigner(SysStorageConfig config, com.ruoyi.file.service.storage.StorageService storageService) {
        AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(
                config.getAccessKey(),
                config.getSecretKey()
        );

        String regionString = resolveRegion(config);
        S3Presigner.Builder builder = S3Presigner.builder()
                .credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
                .endpointOverride(URI.create(config.getEndpoint()))
                .region(Region.of(regionString));

        // 使用StorageService实例的配置
        if (storageService instanceof com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl) {
            com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl baseService = 
                (com.ruoyi.file.service.storage.base.BaseS3StorageServiceImpl) storageService;
            builder.serviceConfiguration(S3Configuration.builder()
                    .pathStyleAccessEnabled(baseService.shouldUsePathStyle())
                    .build());
        } else {
            // 回退到默认配置（虚拟主机风格）
            builder.serviceConfiguration(S3Configuration.builder()
                    .pathStyleAccessEnabled(false)
                    .build());
        }

        return builder.build();
    }

    /**
     * 创建STS客户端
     *
     * @param config 存储配置
     * @return STS客户端
     */
    public static StsClient createStsClient(SysStorageConfig config) {
        AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(
                config.getAccessKey(),
                config.getSecretKey()
        );

        return StsClient.builder()
                .credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
                .region(Region.of(resolveRegion(config)))
                .build();
    }



    /**
     * 规范化区域名
     *
     * @param config 存储配置
     * @return 规范化后的区域名
     */
    public static String resolveRegion(SysStorageConfig config) {
        String region = config.getRegion();
        if (region == null) {
            return "";
        }

        StorageTypeEnum storageType = getStorageType(config);
        if (storageType == StorageTypeEnum.ALIYUN) {
            // 阿里云OSS需要使用如"oss-cn-hangzhou"风格
            if (!region.startsWith("oss-")) {
                return "oss-" + region;
            }
        }

        return region;
    }

    /**
     * 构建文件URL
     *
     * @param protocol    协议（http/https）
     * @param endpoint    端点
     * @param bucketName  桶名
     * @param filePath    文件路径
     * @param config      存储配置
     * @return 文件URL
     */
    public static String buildFileUrl(String protocol, String endpoint, String bucketName, 
                                     String filePath, SysStorageConfig config) {
        StorageTypeEnum storageType = getStorageType(config);
        
        if (storageType == StorageTypeEnum.ALIYUN) {
            // 阿里云OSS使用虚拟主机风格: bucket.endpoint/filePath
            return String.format("%s://%s.%s/%s", protocol, bucketName, endpoint, filePath);
        } else if (storageType == StorageTypeEnum.MINIO) {
            // MinIO使用路径风格: endpoint/bucket/filePath
            return String.format("%s://%s/%s/%s", protocol, endpoint, bucketName, filePath);
        } else {
            // 其他存储类型使用虚拟主机风格
            return String.format("%s://%s.%s/%s", protocol, bucketName, endpoint, filePath);
        }
    }

    /**
     * 获取存储类型枚举
     *
     * @param config 存储配置
     * @return 存储类型枚举，如果未知则返回null
     */
    private static StorageTypeEnum getStorageType(SysStorageConfig config) {
        try {
            return StorageTypeEnum.getByCode(config.getStorageType());
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
}
